Stripe Payment

  • 1. FLOW

    1. When customers are ready to complete their purchase, your application creates a new Checkout Session.

    2. The Checkout Session provides a URL that redirects customers to a Stripe-hosted payment page.

    3. Customers enter their payment details on the payment page and complete the transaction.

    4. After the transaction, a webhook fulfills the order using the checkout.session.completed event.

  • 2. CODE

    1. stripe package

    
                  composer require stripe/stripe-php
    

    After you install the library with Composer, it’s automatically added as a dependency in your project’s composer.json file.

    
    {
        "require": {
            "stripe/stripe-php": "^11.0.0"
        }
    }
    

    2. controller

    When the customer press the 'Place Order' button or 'buy now' button, the given controller function will be executed.

    
    require 'vendor/autoload.php';
    
    \Stripe\Stripe::setApiKey('sk_test_tR3PYbcVNZZ796tH88S4VQ2u');
    
    header('Content-Type: application/json');
    
    $YOUR_DOMAIN = 'http://localhost:4242/public';
    
    $checkout_session = \Stripe\Checkout\Session::create([
      'line_items' => [[
        
        'price' => '{{PRICE_ID}}',
        'quantity' => 1,
      ]],
      'mode' => 'payment',
      'success_url' => $YOUR_DOMAIN . '/success.html',
      'cancel_url' => $YOUR_DOMAIN . '/cancel.html',
    ]);
    
    
    header("HTTP/1.1 303 See Other");
    header("Location: " . $checkout_session->url);
    
    Note that 1) \Stripe\Checkout\Session::create() & 2) $checkout_session->url

    3. Stripe payment page

    header("Location: " . $checkout_session->url); redirect to sripe payment page

    4. webhook

    1. After the payment, customer will be redirected to the success page success.html

    2. Stripe server send the response to the webhook url of our application

    
    
    $payload = @file_get_contents('php://input');
    $event = null;
    
    try {
        $event = \Stripe\Event::constructFrom(
            json_decode($payload, true)
        );
    } catch(\UnexpectedValueException $e) {
        // Invalid payload
        http_response_code(400);
        exit();
    }
    
    // Handle the event
    switch ($event->type) {
        case 'payment_intent.succeeded':
            $paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent
            // Then define and call a method to handle the successful payment intent.
            // handlePaymentIntentSucceeded($paymentIntent);
            break;
        case 'payment_method.attached':
            $paymentMethod = $event->data->object; // contains a \Stripe\PaymentMethod
            // Then define and call a method to handle the successful attachment of a PaymentMethod.
            // handlePaymentMethodAttached($paymentMethod);
            break;
        // ... handle other event types
        default:
            echo 'Received unknown event type ' . $event->type;
    }
    
    http_response_code(200);
    
    
    Live example

    
    try {
                $payload = $request->getContent();
                $serenaHeader = $request->server('HTTP_STRIPE_SIGNATURE');
                $event = null;
    
                
                try {
                    $event = Event::constructFrom(
                        json_decode($payload, true),
                        $serenaHeader,
                        env('STRIPE_WEBHOOK_SECRET')
                    );
                } catch (\UnexpectedValueException $e) {
                    return response('Webhook Error', 400);
                }
    
    
    
               
                
    
                $req = $event->data->object;
                $cs_id = $req->id;
                if(isset($cs_id)){
                    $payment = Payment::where('cs_id', $cs_id);
                }
                    if($payment->exists()) {
                        $payment = $payment->first();
                              
                        // Handle the event
                        switch ($event->type) {
                            case 'checkout.session.completed':
                                // Payment succeeded logic
                               ;
    
                                
                                    $payment_data = [
                                        'trans_id'          => '',
                                        'order_id'          => $req->subscription,
                                        'amount_captured'   => $req->amount_total,
                                        'receipt_url'       => $req->invoice,
                                        'currency'          => $req->currency,
                                        'payment_status'    => $req->payment_status,
                                        'customer_id'       => $req->customer
                                    ];
                                   
    
                                    return response()->json([
                                        'status'        => 200,
                                        'type'          => "success",
                                        'request'       => $request,
                                        'payload'       => $payload,
                                        'cs_id'         =>  $req->id,
                                        'payment_data'  =>  $payment_data,
                                        'payment_stat'  => 'payment done'
                                    ]);
    
    
                                
                                break;
    
                            case 'checkout.session.expired':
                               
                              
                                // Payment failed logic
                                return response()->json([
                                    'status'        => 200,
                                    'type'        => "failed",
                                    'request'     => $request,
                                    'payload'     => $payload,
                                ]);
                                break;
                            
                            // Add other event handlers here
                            default:
                                // Unexpected event type
                                return response('Webhook received unknown event type', 400);
                        }
                        
                    } else {
                        return response()->json([
                            'status'        => 200,
                            'type'          => "success",
                            'request'       => $request,
                            'payload'       => $payload,
                            'cs_id'         =>  $req->id,
                            'payment_stat'  => 'payment not exist'
                        ]);
                    }
    
                    return response('Webhook Handled', 200);
    
            } catch (\Throwable $th) {
                return response()->json([
                    'success'       => false,
                    'message'       => 'Something went wrong!!!',
                    'exception'     => $th->getMessage(),
                    'code'          => $th->getCode(),
                ]);
            }